<?php
/*=============================================================================
|| ##################################################################
||	phpFoX Konsort
|| ##################################################################
||
||	Copyright		: (C) 2005-2007 PHPFOX Limited a Reality Fox Creation
||	Contact			: info@phpfox.com
||
||	- phpFoX and all of its source code and files are protected by Copyright Laws.
||
||	- The license for phpFoX permits you to install this software on a single domain (.com, .org, .net, etc.).
||
||	- You may also not remove this copyright screen which shows the copyright information and credits for phpFoX (RealityFOX Creations).
||
||	- phpFoX Konsort is NOT a FREE software - http://www.phpfox.com/license/
||
|| ##################################################################
=============================================================================*/

/* $File: ./include/modules/Forum/classes/PhpFox_ServiceForum.class.php, $Author:  $ */



/** Service for working with friends
 *
 * @package module.forum
 * @version $Id: PhpFox_ServiceForum.class.php 416 2008-03-28 07:20:51Z phpfoxsv $
 *
 */
class PhpFox_Mod_Forum_ServiceForum extends BaseService
{
    /** Get forums list
     *
     * @return array forums list
     */
    function &getForumList()
    {
		$aForums = $this->oDatabase->getRows("SELECT * FROM ". App::getT('forum') ." ORDER BY forum_title");
        return $aForums;
    }

    /** Get forum list as hash
     * (with caching)
     * @return array forums list as hash (id => title)
     */
    function &getForumHash()
    {
        static $aForums = array(); //forum hash cache
        if (!$aForums)
        {
            $oForum  = $this->_oModule->getItem('Forum');
            /* @var $oForum PhpFox_Mod_Forum_ItemForum */
            $aForums = $oForum->getHash('forum_title');
            foreach ($aForums as $iKey => $sValue)
            {
            	$aForums[$iKey] = App::formatTranslate($sValue);
            }     
        }
        return $aForums;
    }

    /** Creates new forum
     *
     * @param PhpFox_Mod_Forum_ItemForum $oForum      new forum object
     * @param string                     $sImageField uploaded image field name
     */
    function createForum($oForum, $sImageField)
    {
        $oTxt = App::newObject('Text');

        $iCnt = $oForum->oDb->getField('SELECT COUNT(*) FROM '.$oForum->sTable.
                                       '  WHERE forum_title = "'.$oTxt->parseText($oTxt->rmSpecialChars($oForum->aData['forum_title'])).'"');
        if ($iCnt)
        {
            $this->addErrors(App::format('Mod_Forum.forum.duplicate'));
            return false;
        }


        if ($oForum->insert())
        {
            $this->setForumImage($oForum, $sImageField);
            return $oForum->getId();
        }
        else
        {
            $this->addErrors($oForum->getErrors());
        }
        return false;

    }

    /** Creates new forum
     *
     * @param PhpFox_Mod_Forum_ItemForum $oForum      new forum object
     * @param string                     $sImageField uploaded image field name
     */
    function updateForum($oForum, $sImageField)
    {
        $oTxt = App::newObject('Text');

        //check new name for uniqueness
        $iCnt = $oForum->oDb->getField('SELECT COUNT(*) FROM '.$oForum->sTable.
                                       '  WHERE forum_id <> '.$oForum->getId().
                                       '    AND forum_title = "'.$oTxt->parseText($oTxt->rmSpecialChars($oForum->aData['forum_title'])).'"');
        if ($iCnt)
        {
            $this->addErrors(App::format('Mod_Forum.forum.duplicate'));
            return false;
        }


        if ($oForum->update())
        {
            $this->setForumImage($oForum, $sImageField);
            return $oForum->getId();
        }
        else
        {
            $this->addErrors($oForum->getErrors());
        }
        return false;

    }

    /** Set new forum image
     *
     * @param PhpFox_Mod_Forum_ItemForum $oForum forum object
     * @param string                     $sImage uploaded image field name
     */
    function setForumImage(&$oForum, $sImage)
    {
        $oImage = App::newObject('file_Image');
        /* @var $oImage file_Image */
        $sImageFile = 'forum_img_'.$oForum->getId();
        if ($oImage->upload($sImage, App::getParam('forum.pic.path'), $sImageFile, 'jpg'))
        {
            $oImage->makeThumbnail(App::getParam('forum.pic.path').$sImageFile.'.jpg', 40, 40);
            $oForum->aData['img'] = $sImageFile.'.jpg';
            $oForum->update(array('img'));
            return true;
        }
        else
        {
            $this->addErrors($oImage->getErrors());
        }

        return false;
    }

    /** Delete given forum (remove topics, messages and picture)
     *
     * @param int $iForumId forum ID
     */
    function deleteForum($iForumId)
    {
        $oForum = $this->_oModule->getItem('Forum');
        if ($oForum->load($iForumId))
        {
            // delete image
            $sForumImage = App::getParam('forum.pic.path').$oForum->aData['img'];
            if ($oForum->aData['img'] && file_exists($sForumImage))
            {
                unlink($sForumImage);
            }

            //delete all views
            $sSql = 'DELETE FROM '.App::getT('forum_view').' WHERE fid IN '.
                    '  (SELECT ft.id FROM '.App::getT('forum_topic').' AS ft WHERE ft.type = '.$oForum->getId().')';
            $oForum->oDb->query($sSql);

            //delete all replies and topics
            $sSql = 'DELETE FROM '.App::getT('forum_reply').' WHERE fid IN '.
                    '  (SELECT ft.id FROM '.App::getT('forum_topic').' AS ft WHERE ft.type = '.$oForum->getId().')';
            $oForum->oDb->query($sSql);
            $sSql = 'DELETE FROM '.App::getT('forum_topic').' WHERE `type` = '.$oForum->getId();
            $oForum->oDb->query($sSql);

            //delete forum
            $oForum->delete($iForumId);
        }
    }


    /** Delete given topic
     *
     * @param int $iTopicId topic ID
     */
    function deleteTopic(&$oTopic)
    {
        //delete posts
        $sSql = 'DELETE FROM '.App::getT('forum_reply').' WHERE fid = '.$oTopic->getId();
        $oTopic->oDb->query($sSql);

        $iForumId = $oTopic->aData['type'];

        //delete topic
        $oTopic->delete($oTopic->getId());

        $this->updateForumStats($iForumId);
    }

    /** Get forum last post info
     *
     * @param array $aForums forums info
     */
    function addLastPosts($aForums)
    {
        $oDb = &Database::get();
        /* @var $oDb Database */

        $aLastPostIds   = array();
        $aLastTopicIds = array();
        $aLastReplyIds = array();

        foreach($aForums as $aForum)
        {
            if ($aForum['last_reply'])
            {
                $aLastReplyIds[] = $aForum['last_reply'];
            }
            elseif($aForum['last_topic'])
            {
                $aLastTopicIds[] = $aForum['last_topic'];
            }
        }


        //add info from replies (if any)
        $aLastReplies = array();
        if ($aLastReplyIds)
        {
            $aLastReplies = $oDb->getRows('SELECT id, `type`, user, time, fid FROM '.App::getT('forum_reply').
                                          '  WHERE id IN('.implode(',', $aLastReplyIds).')',
                                          true, 'type');
        }
        //add info from topics (if any)
        $aLastTopics = array();
        if ($aLastTopicIds)
        {
            $aLastPosts = $oDb->getRows('SELECT id, `type`, user, time, id AS fid FROM '.App::getT('forum_topic').
                                        '  WHERE id IN('.implode(',', $aLastTopicIds).')',
                                        true, 'type');
        }

        foreach($aForums as $iForumId=>$aForum)
        {
            if (isset($aLastReplies[$iForumId]))
            {
                $aForums[$iForumId]['last_post'] = $aLastReplies[$iForumId];
            }
            elseif (isset($aLastTopics[$iForumId]))
            {
                $aForums[$iForumId]['last_post'] = $aLastTopics[$iForumId];
            }
        }

        return $aForums;
    }

    /** Get forum's topics list and count
     *
     * @param array $aCond     condition
     * @param int   $iPage     page number
     * @param int   $iPageSize page size
     * @return array (0 => topics info, 1 =>total count)
     */
    function getTopicsList($aCond, $iPage = 0, $iPageSize = 0, $sOrder = '', $sUser = '')
    {

        $oTopic = &$this->_oModule->getItem('ForumTopic');
        /* @var $oTopic PhpFox_Mod_Forum_ItemForumTopic */
        $aMap = $oTopic->aFields;
        $aMap['forum_id']    = 'f.forum_id';
        $aMap['forum_title'] = 'f.forum_title';
        if ($sUser)
        {
            $aMap['is_viewed'] = 'fv.id';
        }

        $sCond = $oTopic->_parseCond($aCond, $aMap);
        $sSql = 'SELECT COUNT(*) FROM `'.$oTopic->sTable.'` AS '.$oTopic->sAlias.' WHERE '.$sCond;
        $iCnt = $oTopic->oDb->getField($sSql);
        $aTopics = array();
        if ($iCnt)
        {
            $iOffset = $oTopic->_getOffset($iPage, $iPageSize, $iCnt);
            $sSql = 'SELECT '.$oTopic->_joinFields($aMap).
                    '  FROM `'.$oTopic->sTable.'` AS ft '.
                    '  INNER JOIN '.App::getT('forum').' AS f ON (ft.type = f.forum_id) '.
                    ($sUser ? '  LEFT JOIN '.App::getT('forum_view').' AS fv ON (ft.id = fv.fid AND fv.user = "'.$sUser.'") ' : '').
                    '  WHERE '.$sCond.
                    ($sOrder?(' ORDER BY forum_type DESC, '.$sOrder):'').
                    ($iPageSize?(' LIMIT '.$iOffset.','.$iPageSize):'');
            $aTopics = $oTopic->oDb->getRows($sSql, true);
        }

        //$aTopics = $this->addTopicIinfo($aTopics);
        return array($aTopics, $iCnt);
    }

    /** Add additional info to topics (last post, totals etc.)
     *
     * @deprecated due v1.1 change
     * @param array $aTopics topic list
     * @return array topic list with additional info
     */
    function &addTopicIinfo($aTopics)
    {
        //get IDs
        $aIds = array(0);
        foreach($aTopics as $aTopic)
        {
            $aIds[] = $aTopic['id'];
        }
        $sIds = implode(',', $aIds);

        $oDb = &Database::get();
        /* @var $oDb Database */

        $aReplies = $oDb->getRows('SELECT fid, COUNT(*) AS cnt, MAX(id) AS last_id, MAX(user) '.
                                  '  FROM '.App::getT('forum_reply').
                                  '  WHERE fid IN ('.$sIds.')'.
                                  '  GROUP BY fid', true, 'fid');
        $aViews = $oDb->getRows('SELECT fid, COUNT(*) cnt FROM '.App::getT('forum_view').
                                '  WHERE fid IN ('.$sIds.')'.
                                '  GROUP BY fid', true, 'fid');
        //get last messge
        $aLastRepIds = array();
        foreach($aReplies as $aReply)
        {
            if ($aReply['last_id'])
            {
                $aLastRepIds[] = $aReply['last_id'];
            }
        }
        $sLastRepIds = implode(',', $aLastRepIds);
        //get last replies info
        if ($sLastRepIds)
        {
            $aLastReplies = $oDb->getRows('SELECT fr.id, fr.user, fr.time, fr.fid, u.location FROM '.App::getT('forum_reply').' AS fr '.
                                          '  INNER JOIN '.App::getT('user').' AS u ON(u.user = fr.user) '.
                                          '  WHERE fr.id IN('.$sLastRepIds.')', true, 'fid');
        }

        foreach($aTopics as $k=>$v)
        {
            $iForumId = $v['id'];
            $aTopics[$k]['num_replies'] = isset($aReplies[$iForumId]) ? $aReplies[$iForumId]['cnt'] : 0;
            //$aTopics[$k]['num_views'] = isset($aViews[$iForumId]) ? $aViews[$iForumId]['cnt'] : 0;
            $aTopics[$k]['last_reply'] = isset($aLastReplies[$iForumId]) ? $aLastReplies[$iForumId] : array();
        }

        return $aTopics;
    }

    /** Get topic's posts list and count
     *
     * @param array $aCond     condition
     * @param int   $iPage     page number
     * @param int   $iPageSize page size
     * @return array (0 => posts info, 1 =>total count)
     */
    function getPostsList($aCond, $iPage = 0, $iPageSize = 0, $sSort = '')
    {
        $oReply = &$this->_oModule->getItem('ForumReply');
        /* @var $oReply PhpFox_Mod_Forum_ItemForumReply */

        $aMap = $oReply->aFields;
        $aMap['user_headline'] = 'u.headline';
        $aMap['user_type']     = 'u.type';
        $aMap['user_points']     = 'p.total';

        $sCond = $oReply->_parseCond($aCond, $aMap);
        $sSql = 'SELECT COUNT(*) FROM `'.$oReply->sTable.'` AS '.$oReply->sAlias.' WHERE '.$sCond;
        $iCnt = $oReply->oDb->getField($sSql);
        $aReplies = array();
        if ($iCnt)
        {
            $iOffset = $oReply->_getOffset($iPage, $iPageSize, $iCnt);
            $sSql = 'SELECT '.$oReply->_joinFields($aMap).
                    '  FROM `'.$oReply->sTable.'` AS frr '.
                    '  INNER JOIN '.App::getT('user').' AS u ON (frr.user = u.user)
                       LEFT JOIN '. App::getT('user_info') .' AS p
	    			   ON p.user = frr.user
                    '.
                    '  WHERE '.$sCond.
                    ($sSort?(' ORDER BY '.$sSort):'').
                    ($iPageSize?(' LIMIT '.$iOffset.','.$iPageSize):'');
            $aReplies = $oReply->oDb->getRows($sSql, true);
        }

        return array($aReplies, $iCnt);
    }

    /** Add new topic to forum
     *
     * @param PhpFox_Mod_Account_ItemAccount  $oUser     author's account object
     * @param PhpFox_Mod_Forum_ItemForum      $oForum  forum ID
     * @param string                          $sTitle    topic title
     * @param string                          $sText     message text
     */
    function addTopic($oUser, $oForum, $sTitle, $sText, $iForumType = 0)
    {
        $oTopic = $this->_oModule->getItem('ForumTopic');
        //check topic title uniquesness

        $iCnt = $oTopic->oDb->getField('SELECT COUNT(*) FROM '.$oTopic->sTable.
                                       '  WHERE `type` = '.$oForum->aData[$oForum->sId].
                                       '    AND  title = "'.$oTopic->oDb->escape($sTitle).'"');
        if ($iCnt)
        {
            $this->addErrors(App::format('Mod_Forum.error.duplicate'));
            return false;
        }

        $oTxt = App::newObject('Text');
        $oTopic->aData = array(
            'type'  => $oForum->getId(),
            'user'  => $oUser->aData['user'],
            'title' => $sTitle,
            'text'  => $oTxt->preParseText($sText),
            'forum_type' => $iForumType,
            'time'  => time(),
        );

        $iTopicId = $oTopic->insert();
        if ($iTopicId)
        {
            $this->updateTopicStats($oTopic->getId(), false);
        }

        $oDb = &Database::get();
        $aRow = $oDb->getRow('SELECT COUNT(*) AS cnt, SUM(total_replies) AS cnt_replies '.
                                       '  FROM '.App::getT('forum_topic').
                                       '  WHERE `type` = '.$oForum->getId());

        $oDb->query("UPDATE ". App::getT('forum') ."  SET
        	total_topics = '". $aRow['cnt'] ."',
        	total_posts = '". $aRow['cnt_replies'] ."',
        	last_time = '". time() ."',
        	last_user = '". $oUser->aData['user'] ."',
        	last_thread = '". $sTitle ."',
        	last_id = '". $iTopicId ."'
        	WHERE forum_id = '". $oForum->getId() ."'
			");

        return $iTopicId;
    }

    /** Add reply to topic
     *
     * @param PhpFox_Mod_Account_ItemAccount  $oUser   author's account object
     * @param PhpFox_Mod_Forum_ItemForumTopic $oTopic  forum topic (to add reply)
     * @param string                          $sText   reply text
     * @return int reply ID or false on error
     */
    function addReply($oUser, $oTopic, $sText, $sQuotedUser = '')
    {
        $oReply = $this->_oModule->getItem('ForumReply');
        $oTxt = App::newObject('Text');
        $oReply->aData = array(
            'fid'  => $oTopic->getId(),
            'user' => $oUser->aData['user'],
            'type' => $oTopic->aData['type'],
            'text' => $oTxt->preParseText($sText),
            'time' => time(),
        );
        $iReplyId = $oReply->insert();

        if ($iReplyId)
        {
            $this->updateTopicStats($oTopic->getId());
        }

        //send mail on post reply
        $oMailer = &App::newObject('mail_Mailer');
        /* @var $oMailer mail_Mailer */

        $oSrvAcc = &App::getModuleService('Account', 'Account');
        /* @var $oSrvAcc PhpFox_Mod_Account_ServiceAccount */
        $oTpl = &App::getTemplate();
            
        if ($oTopicAuthor = $oSrvAcc->getByUsername($oTopic->aData['user']))
        {
            if ($oTopicAuthor->aData['not_4'] &&
                   ($oTopicAuthor->aData['user'] != $oUser->aData['user']) )
            {
                $aVars = array(
                    'TO'        => $oTopicAuthor->aData['user'],
                    'FROM'      => $oUser->aData['user'],
                    'SITENAME'  => App::getSetting('site_name'),
                    'FORUM_URL' => App::makeUrl('public.forum.posts', array('page' => 'last', 'id' => $oTopic->aData['id'])),
                ); 
                $oMailer->send('email_forum', $oTopicAuthor->aData['email'],
                               App::format('core.forum.reply'), $aVars);
            }        		               
        }
        
        if ($oQuotedUser = $oSrvAcc->getByUsername($sQuotedUser))
        {
            if ($oQuotedUser->aData['not_4'] &&
                   ($oQuotedUser->aData['user'] != $oUser->aData['user']) &&
                   ($oQuotedUser->aData['user'] != $oTopicAuthor->aData['user']) )
               {
                $aVars = array(
                    'TO'        => $oQuotedUser->aData['user'],
                    'FROM'      => $oUser->aData['user'],
                    'SITENAME'  => App::getSetting('site_name'),
                    'FORUM_URL' => App::makeUrl('public.forum.posts', array('page' => 'last', 'id' => $oTopic->aData['id'])),
                       'IMG'       => App::getParam('user.pic.url').App::getSetting('user_upload_location').$oUser->aData['user'].'.jpg'
                );
                $oMailer->send('email_quote', $oQuotedUser->aData['email'],
                               App::format('core.forum.reply'), $aVars);
               }
        }

        return $iReplyId;
    }

    /** Update statistics on topic (and parent forum)
     *
     * @param int $iTopicId topic ID
     * @return bool true - update ok, false - error (no such topic, etc.)
     */
    function updateTopicStats($iTopicId, $bUpdateCount = true)
    {
        $oTopic = $this->_oModule->getItem('ForumTopic');
        /** @var $oTopic PhpFox_Mod_Forum_ForumTopic */
        if (! $oTopic->load($iTopicId))
        {
            return false;
        }


        //update topic stats

        $sSql = 'SELECT id, `user`, `time` FROM '.App::getT('forum_reply').
                '  WHERE fid = '.$iTopicId.
                '  ORDER BY `time` DESC LIMIT 1';
        $aReply = $oTopic->oDb->getRow($sSql);
        if ($aReply) //topic has replies
        {
            $oTopic->aData['last_user']  = $aReply['user'];
            $oTopic->aData['last_time']  = $aReply['time'];
            $oTopic->aData['last_id']    = $aReply['id'];
        }
        else //no replies got last info from topic itself
        {
            $oTopic->aData['last_user']  = $oTopic->aData['user'];
            $oTopic->aData['last_time']  = $oTopic->aData['time'];
            $oTopic->aData['last_id']    = 0;
        }
        $oTopic->aData['total_replies'] = $oTopic->oDb->getField('SELECT COUNT(*) FROM '.App::getT('forum_reply').
                                                                 '  WHERE fid = '.$oTopic->getId());

        $oTopic->update(array('total_replies', 'last_user', 'last_time', 'last_id'));

		if ( $bUpdateCount )
		{
        	$this->updateForumStats($oTopic->aData['type']);
        }

        return true;
    }

    function updateForumStats($iForumId)
    {
        $oForum = $this->_oModule->getItem('Forum');
        /** @var $oTopic PhpFox_Mod_Forum_Forum */

        if (! $oForum->load($iForumId))
        {
            return false;
        }

        $aRow = $oForum->oDb->getRow('SELECT COUNT(*) AS cnt, SUM(total_replies) AS cnt_replies '.
                                       '  FROM '.App::getT('forum_topic').
                                       '  WHERE `type` = '.$oForum->getId());

        $oForum->aData['total_topics'] = $aRow['cnt'];
        $oForum->aData['total_posts']  = $aRow['cnt_replies'];

        if ($oForum->aData['total_topics']) //have at least one topic
        {
            $sSql = 'SELECT r.id, r.fid, r.user, r.time, t.title FROM '.App::getT('forum_reply').' AS r, '.App::getT('forum_topic').' AS t '.
                    '  WHERE t.type = '.$iForumId.' AND t.id = r.fid '.
                    '  ORDER BY r.time DESC LIMIT 1';

            $aTopic = $oForum->oDb->getRow($sSql);

            $oForum->aData['last_time']   = $aTopic['time'];
            $oForum->aData['last_user']   = $aTopic['user'];
            $oForum->aData['last_thread'] = $aTopic['title'];
            $oForum->aData['last_id']     = $aTopic['fid'];
            $oForum->aData['last_url']    = $aTopic['id'];

        }
        else //no topics
        {
            $oForum->aData['last_time']   = 0;
            $oForum->aData['last_user']   = '';
            $oForum->aData['last_thread'] = '';
            $oForum->aData['last_id']     = 0;
            $oForum->aData['last_url']    = 0;
        }

        $oForum->update(array('total_topics', 'total_posts', 'last_time', 'last_user', 'last_thread', 'last_id', 'last_url'));
    }


    /** Get topic additional info
     *
     * @param PhpFox_Mod_Forum_ItemForumTopic $oTopic topic
     * @return array ('num_reply' => number of replies, 'num_views' => num views)
     */
    function getTopicAddInfo($oTopic)
    {
        $aRes = array();
        $aRes['num_replies'] = $oTopic->oDb->getField('SELECT COUNT(*) FROM '.App::getT('forum_reply').
                                                      '  WHERE fid = '.$oTopic->aData[$oTopic->sId]);
        $aRes['num_views']   = $oTopic->oDb->getField('SELECT COUNT(*) FROM '.App::getT('forum_view').
                                                      '  WHERE fid = '.$oTopic->aData[$oTopic->sId]);

        return $aRes;
    }

    /** Mark topic as viewed by given user
     *
     * @param PhpFox_Mod_Forum_ItemForumTopic $oTopic topic to mark
     * @param PhpFox_Mod_Account_ItemAccount   $oUser user who views topic
     */
    function markTopicView($oTopic, $oUser)
    {
        if ($oTopic && $oUser)
        {
            $iCnt = $oTopic->oDb->getField('SELECT COUNT(*) FROM '.App::getT('forum_view').
                                           '  WHERE fid = '.intval($oTopic->aData[$oTopic->sId]).
                                           '    AND user = "'.$oUser->aData['user'].'"');
            if (!$iCnt)
            {
                $aVals = array(
                    'fid'  => $oTopic->aData[$oTopic->sId],
                    'user' => $oUser->aData['user'],
                    'time' => time(),
                );
                $oTopic->oDb->insert(App::getT('forum_view'), $aVals);
            }
        }
    }

    /** Mark all topics as viewed
     *
     * @param PhpFox_Mod_Account_ItemAccount $oUser user account
     */
    function markAllTopicView($oUser)
    {
        if ($oUser)
        {
            $sSql = 'INSERT INTO `'.App::getT('forum_view').'`'.
                    '  (fid, user, time) '.
                    '  SELECT ft.id, "'.$oUser->aData['user'].'", '.time().'  FROM '. App::getT('forum_topic') .' AS ft '.
                    '      LEFT JOIN '. App::getT('forum_view') .' AS fv ON (ft.id  = fv.fid AND fv.user = "'.$oUser->aData['user'].'") '.
                    '    WHERE fv.id IS NULL';
            $oUser->oDb->query($sSql);
        }
    }

    /** Move topic to another forum
     *
     * @param PhpFox_Mod_Forum_ItemForumTopic $oTopic    topic object
     * @param int                             $iForumId  target forum ID
     * @return bool true - move ok, false - error occured
     */
    function moveTopic(&$oTopic, $iForumId)
    {
        $iForumId = intval($iForumId);
        $oForum = &$this->_oModule->getItem('Forum');
        /* @var $oForum PhpFox_Mod_Forum_ItemForum */

        if ($oForum->load($iForumId))
        {
            $iOldForumId = $oTopic->aData['type'];
            $iNewForumId = intval($iForumId);
            $oTopic->aData['type'] = intval($iForumId);
            if ($oTopic->update(array('type')))
            {
                //move replies
                $aVals = array('type' => $iNewForumId);
                $oTopic->oDb->update(App::getT('forum_reply'), $aVals,
                                     'fid = '.$oTopic->getId());

                //update statistics
                $this->updateForumStats($iOldForumId);
                $this->updateForumStats($iNewForumId);
                return true;
            }
            else
            {
                $this->addErrors($oTopic->getErrors());
            }
        }
        else
        {
            $this->addErrors('Mod_Forum.error.wrong.forum');
        }

        return false;
    }

    /** Increment view counter for topic.
     *
     * @param PhpFox_Mod_Forum_ItemForumTopic $oTopic viewed topic
     */
    function addTopicView(&$oTopic)
    {
        if (!$this->_oModule->getSessVar('Viewed_'.$oTopic->getId()))
        {
            $oTopic->aData['view']++;
            $oTopic->update(array('view'));
            $this->_oModule->setSessVar('Viewed_'.$oTopic->getId(), 1);
        }
    }

    /** Callback handler for create account
     *
     * @param array $aParams parameters
     */
    function onCreateAccount($aParams)
    {
    	/*
        if(PHPFOX_VB)
        {
            App::plugin_createUser($aParams['Account']);
        }
        */
        return true;
    }


    /** Callback handler for delete account
     *
     * @param array $pArams parameteres
     */
    function onDeleteAccount($aParams)
    {
        $oAcc = &$aParams['oAcc'];

	    foreach($aParams['aIds'] as $iAccId)
	    {
	        $oAcc->load($iAccId);

            //delete user's messages
            $oReply = $this->_oModule->getItem('ForumReply');
            $sSql = 'SELECT fid FROM '.$oReply->sTable.
                    '  WHERE `user` = "'.$oAcc->aData['user'].'"'.
                    '  GROUP BY fid ';
            $aRows = $oReply->oDb->getRows($sSql);
            $sSql = 'DELETE FROM '.$oReply->sTable.
                    '  WHERE `user` = "'.$oAcc->aData['user'].'"';
            $oReply->oDb->query($sSql);
            
            $oTopic = $this->_oModule->getItem('ForumTopic');
            //delete user's topics
            $sSql = 'SELECT id FROM '.$oTopic->sTable.
                    '  WHERE `user` = "'.$oAcc->aData['user'].'"';

            foreach($oTopic->oDb->getRows($sSql) as $aRow)
            {
                if ($oTopic->load($aRow['id']))
                {
                    $this->deleteTopic($oTopic);
                }
            }

            //update topics
            foreach($aRows as $aRow)
            {
                $this->updateTopicStats($aRow['fid']);
            }
            
            $sSql = ' DELETE FROM '. App::getT('forum_view') .' WHERE user=\''. $oAcc->aData['user'] .'\' ';
            $oReply->oDb->query($sSql);
        }
    }

    /** Does user can write post.
     * Method checkis membership permissions, blocking status toward topic starter,.
     *
     * @var int                             $iTopicId target topic ID
     * @var PhpFox_Mod_Account_ItemAccount  $oAcc     current user (who try to write)
     * @return bool true - can post, false - cannot post
     */
    function canWritePost($iTopicId, $oAcc)
    {
        $oTopic = $this->_oModule->getItem('ForumTopic');
        if (!$oTopic->load($iTopicId))
        {
            return false; //no such topic
        }

        $oSrvSec = &App::getModuleService('Account', 'Security');
	    /* @var $oSrvSec PhpFox_Mod_Account_ServiceSecurity */

        if ('full' != $oSrvSec->getPerm('forum'))
        {
            return false;
        }

        $oSrvAcc = &App::getModuleService('Account', 'Account');
        /* @var $oSrvAcc PhpFox_Mod_Account_ServiceAccount */
        $oTopicAuthor = $oSrvAcc->getByCondition('user ="'.$oTopic->aData['user'].'"');

        $oSrvBlock = &App::getModuleService('Account', 'Block');
        /* @var $oSrvBlock PhpFox_Mod_Account_ServiceBlock */
        if ( $oSrvBlock->isBlocked($oTopicAuthor, $oAcc) )
        {
            return false;
        }

        //all passed ok -- return true;
        return true;
    }
}
?>